/**
 * 1. 接口的面向对象的特征
 * 比抽象类还要抽象 在接口中就只能有抽象的属性和方法，不能有具体的实现
 */

/**
 * 抽象类 abstract
 */
abstract class Foo {
  abstract name: string;
  show() {}
}
/**
 * 接口 interface
 */
interface FooInterface {
  name: string;
  show(): string;
}

/**
 * 2. 接口不能使用访问修饰符 public static private protect
 */
/**
 * 3. 类和接口的实现使用implements关键字 extends不行，因为，tsc编译之后，interface会消失
 */
class Bzz implements FooInterface {
  name: string = "你好";
  show() {
    return this.name;
  }
}
/**
 * 4. 接口可以多实现
 */
interface Bar {
  show2(): string;
}
class Bzz2 implements Foo, Bar {
  show2(): string {
    throw new Error("Method not implemented.");
  }
  name: string;
  show(): void {
    throw new Error("Method not implemented.");
  }
}

/**
 *  5. 接口和接口之间使用extends 继承
 */

/**
 * 6. 接口的使用理解
 * 具体实现，不管，只是一个上层抽象
 *
 */
class User {
  constructor(public id: number, public name: string) {}
}
interface Repository<T> {
  /**
   * 根据id查询user
   * @param id
   */
  findById(id: number): T | undefined;
  save(item: T): void;
  delete(item: T): boolean;
}

class UserRepository implements Repository<User> {
  private users = new Map<number, User>();

  findById(id: number): User | undefined {
    return this.users.get(id);
  }
  save(item: User): void {
    this.users.set(item.id, item);
  }
  delete(item: User): boolean {
    return this.users.delete(item.id);
  }
}
